package com.ruoyi.ruoyiqywechat.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.qy.config.CrmebConfig;
import com.ruoyi.common.qy.constants.Constants;
import com.ruoyi.common.qy.domain.SystemConfig;
import com.ruoyi.common.qy.exception.CrmebException;
import com.ruoyi.common.redis.utils.RedisUtil;
import com.ruoyi.ruoyiqywechat.dao.SystemConfigDao;
import com.ruoyi.ruoyiqywechat.service.SystemConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;

/**
 * SystemConfigServiceImpl 接口实现
 * +----------------------------------------------------------------------
 * | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
 * +----------------------------------------------------------------------
 * | Author: CRMEB Team <admin@crmeb.com>
 * +----------------------------------------------------------------------
 */
@Service
public class SystemConfigServiceImpl extends ServiceImpl<SystemConfigDao, SystemConfig> implements SystemConfigService {

    @Resource
    private SystemConfigDao dao;
    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private CrmebConfig crmebConfig;
    /**
     * 根据menu name 获取 value
     *
     * @param name menu name
     * @return String
     */
    @Override
    public String getValueByKey(String name) {
        return get(name);
    }
    /**
     * 根据 name 获取 value 找不到抛异常
     *
     * @param name menu name
     * @return String
     */
    @Override
    public String getValueByKeyException(String name) {
        String value = get(name);
        if (StrUtil.isBlank(value)) {
            throw new CrmebException("没有找到或配置：" + name + "数据");
        }
        return value;
    }
    /**
     * 获取config数据
     *
     * @param name key
     * @return String
     */
    private String get(String name) {
        if (!crmebConfig.isAsyncConfig()) {
            SystemConfig systemConfig = getByName(name);
            if (ObjectUtil.isNull(systemConfig) || StrUtil.isBlank(systemConfig.getValue())) {
                return "";
            }
            return systemConfig.getValue();
        }
        Long size = redisUtil.getHashSize(Constants.CONFIG_LIST);
        if (size <= 0) {
            SystemConfig systemConfig = getByName(name);
            if (ObjectUtil.isNull(systemConfig) || StrUtil.isBlank(systemConfig.getValue())) {
                asyncBlank(name);
                return "";
            }
            async(systemConfig);
            return systemConfig.getValue();
        }
        Object data = redisUtil.hget(Constants.CONFIG_LIST, name);
        if (ObjectUtil.isNotNull(data)) {
            return data.toString();
        }
        SystemConfig systemConfig = getByName(name);
        if (ObjectUtil.isNull(systemConfig) || StrUtil.isBlank(systemConfig.getValue())) {
            asyncBlank(name);
            return "";
        }
        async(systemConfig);
        return systemConfig.getValue();
    }
    /**
     * 初始化时加载config_list缓存
     */
    @PostConstruct
    public void loadingConfigCache() {
        if (!crmebConfig.isAsyncConfig()) {
            return;
        }
        if (redisUtil.exists(Constants.CONFIG_LIST)) {
            Long hashSize = redisUtil.getHashSize(Constants.CONFIG_LIST);
            if (hashSize > 0) {
                return;
            }
        }
        LambdaQueryWrapper<SystemConfig> lqw = Wrappers.lambdaQuery();
        lqw.select(SystemConfig::getName, SystemConfig::getValue);
        lqw.eq(SystemConfig::getStatus, false);
        List<SystemConfig> systemConfigList = dao.selectList(lqw);
        systemConfigList.forEach(config -> redisUtil.hset(Constants.CONFIG_LIST, config.getName(), config.getValue()));

    }

    private SystemConfig getByName(String name) {
        LambdaQueryWrapper<SystemConfig> lqw = Wrappers.lambdaQuery();
        lqw.select(SystemConfig::getId, SystemConfig::getName, SystemConfig::getValue);
        lqw.eq(SystemConfig::getStatus, false);
        lqw.eq(SystemConfig::getName, name);
        lqw.orderByDesc(SystemConfig::getId);
        lqw.last(" limit 1");
        return dao.selectOne(lqw);
    }
    private void asyncBlank(String key) {
        redisUtil.hset(Constants.CONFIG_LIST, key, "");
    }

    private void async(SystemConfig systemConfig) {
        redisUtil.hset(Constants.CONFIG_LIST, systemConfig.getName(), systemConfig.getValue());
    }

}

